/**
 * md5计算
 * @param str string|number 字符串  强制转为字符串
 * @param L16 boolean 是否返回16位长度  false:32位
 * @param up boolean 是否返回大写  false:小写
 * @return string
 */
$.md5 = function(str, L16=false, up=false){
	const HEX = '0123456789abcdef';
	function ADD (x, y){
		let lsw = (x&0xffff) + (y&0xffff);
		let msw = (x>>16) + (y>>16) + (lsw>>16);
		return (msw<<16) | (lsw&0xffff);
	}
	function CMN (q, a, b, x, s, t){
		let num = ADD(ADD(a,q), ADD(x,t));
		return ADD((num<<s)|(num>>>(32-s)), b);
	}
	function F(a, b, c, d, x, s, t){ return CMN((b&c)|(~b&d), a, b, x, s, t); }
	function G(a, b, c, d, x, s, t){ return CMN((b&d)|(c&~d), a, b, x, s, t); }
	function H(a, b, c, d, x, s, t){ return CMN(b^c^d, a, b, x, s, t); }
	function I(a, b, c, d, x, s, t){ return CMN(c^(b|~d), a, b, x, s, t); }
	function BINL(x, len){
		x[len>>5]|=0x80<<(len%32);  x[((len+64)>>>9<<4)+14]=len;
		let oa, ob, oc, od, a=1732584193, b=-271733879, c=-1732584194, d=271733878;
		for (let i=0; i<x.length; i+=16) {
			oa=a;  ob=b;  oc=c;  od=d;

			a=F(a,b,c,d,x[i]   ,7 ,-680876936);  d=F(d,a,b,c,x[i+1] ,12,-389564586);
			c=F(c,d,a,b,x[i+2] ,17,606105819);   b=F(b,c,d,a,x[i+3] ,22,-1044525330);
			a=F(a,b,c,d,x[i+4] ,7 ,-176418897);  d=F(d,a,b,c,x[i+5] ,12,1200080426);
			c=F(c,d,a,b,x[i+6] ,17,-1473231341); b=F(b,c,d,a,x[i+7] ,22,-45705983);
			a=F(a,b,c,d,x[i+8] ,7 ,1770035416);  d=F(d,a,b,c,x[i+9] ,12,-1958414417);
			c=F(c,d,a,b,x[i+10],17,-42063);      b=F(b,c,d,a,x[i+11],22,-1990404162);
			a=F(a,b,c,d,x[i+12],7 ,1804603682);  d=F(d,a,b,c,x[i+13],12,-40341101);
			c=F(c,d,a,b,x[i+14],17,-1502002290); b=F(b,c,d,a,x[i+15],22,1236535329);

			a=G(a,b,c,d,x[i+1] ,5 ,-165796510);  d=G(d,a,b,c,x[i+6] ,9 ,-1069501632);
			c=G(c,d,a,b,x[i+11],14,643717713);   b=G(b,c,d,a,x[i]   ,20,-373897302);
			a=G(a,b,c,d,x[i+5] ,5 ,-701558691);  d=G(d,a,b,c,x[i+10],9 ,38016083);
			c=G(c,d,a,b,x[i+15],14,-660478335);  b=G(b,c,d,a,x[i+4] ,20,-405537848);
			a=G(a,b,c,d,x[i+9] ,5 ,568446438);   d=G(d,a,b,c,x[i+14],9 ,-1019803690);
			c=G(c,d,a,b,x[i+3] ,14,-187363961);  b=G(b,c,d,a,x[i+8] ,20,1163531501);
			a=G(a,b,c,d,x[i+13],5 ,-1444681467); d=G(d,a,b,c,x[i+2] ,9 ,-51403784);
			c=G(c,d,a,b,x[i+7] ,14,1735328473);  b=G(b,c,d,a,x[i+12],20,-1926607734);

			a=H(a,b,c,d,x[i+5] ,4 ,-378558);     d=H(d,a,b,c,x[i+8] ,11,-2022574463);
			c=H(c,d,a,b,x[i+11],16,1839030562);  b=H(b,c,d,a,x[i+14],23,-35309556);
			a=H(a,b,c,d,x[i+1] ,4 ,-1530992060); d=H(d,a,b,c,x[i+4] ,11,1272893353);
			c=H(c,d,a,b,x[i+7] ,16,-155497632);  b=H(b,c,d,a,x[i+10],23,-1094730640);
			a=H(a,b,c,d,x[i+13],4 ,681279174);   d=H(d,a,b,c,x[i]   ,11,-358537222);
			c=H(c,d,a,b,x[i+3] ,16,-722521979);  b=H(b,c,d,a,x[i+6] ,23,76029189);
			a=H(a,b,c,d,x[i+9] ,4 ,-640364487);  d=H(d,a,b,c,x[i+12],11,-421815835);
			c=H(c,d,a,b,x[i+15],16,530742520);   b=H(b,c,d,a,x[i+2] ,23,-995338651);

			a=I(a,b,c,d,x[i]   ,6 ,-198630844);  d=I(d,a,b,c,x[i+7] ,10,1126891415);
			c=I(c,d,a,b,x[i+14],15,-1416354905); b=I(b,c,d,a,x[i+5] ,21,-57434055);
			a=I(a,b,c,d,x[i+12],6 ,1700485571);  d=I(d,a,b,c,x[i+3] ,10,-1894986606);
			c=I(c,d,a,b,x[i+10],15,-1051523);    b=I(b,c,d,a,x[i+1] ,21,-2054922799);
			a=I(a,b,c,d,x[i+8] ,6 ,1873313359);  d=I(d,a,b,c,x[i+15],10,-30611744);
			c=I(c,d,a,b,x[i+6] ,15,-1560198380); b=I(b,c,d,a,x[i+13],21,1309151649);
			a=I(a,b,c,d,x[i+4] ,6 ,-145523070);  d=I(d,a,b,c,x[i+11],10,-1120210379);
			c=I(c,d,a,b,x[i+2] ,15,718787259);   b=I(b,c,d,a,x[i+9] ,21,-343485551);

			a=ADD(a,oa); b=ADD(b,ob); c=ADD(c,oc); d=ADD(d,od);
		}
		return [a, b, c, d];
	}
	$.md5 = function(str, L16, up){
		str=$.char(str);  let rtn='', arr=[]; arr[(str.length>>2)-1]=undefined;
		let L8=str.length*8;  for(let i=0; i<arr.length; i++) arr[i]=0;
		for(let i=0; i<L8; i+=8) arr[i>>5]|=(str.charCodeAt(i/8)&0xff)<<(i%32);
		let out='', tmp=BINL(arr,L8), i=0, len=tmp.length*32;
		for(; i<len; i+=8) out+=String.fromCharCode((tmp[i>>5]>>>(i%32))&0xff);
		for(let i=0; i<out.length; i++){
			let x = out.charCodeAt(i);
			rtn += HEX.charAt((x>>>4)&0x0f)+HEX.charAt(x&0x0f);
		}
		if(L16) rtn=rtn.slice(8,24);  return up?rtn.toUpperCase():rtn;
	};
	return $.md5(str, L16, up);
};
